﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace RandomDemo
{
    public class TestClass
    {
        public void TestMedtod()
        {
            Model model = new Model();
            model.Id = 1;
            model.Str = "蒲磊";
            model.TList = new List<string>() { "list1", "list2" };
            model.Model1 = new Model1() { Str = "str", Id = 5 };

            model.ListModel1 = new List<Model1>() { new Model1() { Id = 101, Str = "aaaaa" }, new Model1() { Id = 102, Str = "bbbb" } };
            model.Modelss = new List<List<Model1>>();
            model.Modelss.Add(model.ListModel1);

            model.PArray = new Array[10];
            model.PArrayList = new ArrayList();
            model.PArrayList.Add(model.Model1);
            model.PArrayList.Add("后弦");
            model.Listssss = new List<List<List<string>>>() { new List<List<string>>() { new List<string>() { "格林家的公主" } } };
            Model model1 = new Model();

            


            TestDictionary test = new TestDictionary();
            test.PDictionary = new Dictionary<string, int>();
            test.PDictionary.Add("PP", 1);
            test.PDictionary.Add("xx", 12);
            test.PDictionary1 = new Dictionary<string, Model1>();
            test.PDictionary1.Add("xx", new Model1() { Id=1,Str="1"});
            test.PDictionary1.Add("bb", new Model1() { Id=2,Str="2"});
            TestDictionary test1 = new TestDictionary();
            test1.PDictionary = new Dictionary<string, int>();
            ObjectClone(model1, model);

            model.ListModel1[0].Id = 100000000;
            //ObjectClone(i1, i);
        }
        public bool ObjectClone(object newObj, object oldObj)
        {
            if (newObj == null || oldObj == null)
            {
                return false;
            }
            Type newType = newObj.GetType();
            Type oldType = oldObj.GetType();
            if (newType == oldType)
            {
                if (oldType.GetProperties().Length == 0)
                {
                    return false;
                }
                //循环取属性
                foreach (var item in newType.GetProperties())
                {
                    var oldValue = item.GetValue(oldObj);
                    if (oldValue == null)
                    {
                        continue;
                    }
                    //值类型直接赋值
                    if (oldValue is string || oldValue.GetType().GetProperties().Length == 0)
                    {
                        item.SetValue(newObj, oldValue);
                    }
                    //集合的话，调用集合的克隆方法
                    else if (oldValue is ArrayList||oldValue.GetType().GetMethod("GetEnumerator") != null)
                    {
                        //数组处理不了，跳出本次循环
                        if(oldValue is Array)
                        {
                            continue;
                        }
                        else
                        {
                            //初始化
                            item.SetValue(newObj, System.Activator.CreateInstance(oldValue.GetType()));
                            ListClone(item.GetValue(newObj), oldValue);
                        }
                        
                    }
                    //如果是引用类型，也就是对象，则调用对象的克隆方法，也需要先初始化操作
                    else
                    {
                        if (item.GetValue(newObj) == null)
                        {
                            item.SetValue(newObj, System.Activator.CreateInstance(oldValue.GetType()));
                        }
                        ObjectClone(item.GetValue(newObj), item.GetValue(oldObj));
                    }
                }

                return true;
            }
            return false;
        }


        public bool ListClone(object newList, object oldList)
        {
            if (newList == null || oldList == null)
            {
                return false;
            }
            Type newType = newList.GetType();
            Type oldType = oldList.GetType();
            //判断相同类型
            if (newType == oldType)
            {
                //如果有枚举方法并且不是字典
                if (oldList is ArrayList|| oldType.GetMethod("GetEnumerator") != null )
                {
                    //如果是字典
                    if (oldType.GetMethod("ContainsKey") != null)
                    {
                        
                        foreach (var dirValue in (oldList as dynamic))
                        {
                            var keyValue = (dirValue as dynamic).Key;
                            var valueValue = (dirValue as dynamic).Value;
                            if (keyValue is string || keyValue.GetType().GetProperties().Length == 0)
                            {

                            }
                            else
                            {
                                //初始化
                                keyValue = System.Activator.CreateInstance((dirValue as dynamic).Key.GetType());
                                ObjectClone(keyValue, (dirValue as dynamic).Key);
                            }

                            if (valueValue is string || valueValue.GetType().GetProperties().Length == 0)
                            {

                            }
                            else
                            {
                                //初始化
                                valueValue = System.Activator.CreateInstance((dirValue as dynamic).Value.GetType());
                                ObjectClone(valueValue, (dirValue as dynamic).Value);
                            }
                            (newList as dynamic).Add(keyValue, valueValue);
                        }
                    }
                    //有add方法的才用，数组Array比较复杂没搞
                    else if (oldType.GetMethod("Add") != null)
                    {
                        //遍历集合取值
                        foreach (object listItem in (oldList as dynamic))
                        {
                            //如果是值类型，直接添加
                            if (listItem is string || listItem.GetType().GetProperties().Length == 0)
                            {
                                newList.GetType().GetMethod("Add").Invoke(newList, new object[] { listItem });
                            }
                            else
                            {
                                //先实例化
                                var listValue = System.Activator.CreateInstance(listItem.GetType());
                                //如果他还是集合，则递归调用自己进行赋值操作
                                if (listValue.GetType().GetMethod("GetEnumerator") != null)
                                {
                                    ListClone(listValue, listItem);
                                }
                                //否则调用对象克隆的方法进行赋值操作
                                else
                                {
                                    ObjectClone(listValue, listItem);
                                }
                                //将克隆好的引用对象赋给NewObj
                                newList.GetType().GetMethod("Add").Invoke(newList, new object[] { listValue });
                            }
                        }
                    }

                }
            }

            return false;
        }
    }

    public class Model
    {
        public string Str { get; set; }
        public int Id { get; set; }

        public List<string> TList { get; set; }

        public List<Model1> ListModel1 { get; set; }
        public List<List<Model1>> Modelss { get; set; }
        public Model1 Model1 { get; set; }
        public Array PArray { get; set; }

        public List<List<List<string>>> Listssss { get; set; }
        public ArrayList PArrayList { get; set; }
    }

    public class Model1
    {
        public int Id { get; set; }
        public string Str { get; set; }
    }

    public class TestDictionary
    {
        public Dictionary<string,int> PDictionary { get; set; }
        public Dictionary<string,Model1> PDictionary1 { get; set; }
    }
}
